package com.lp.security.schedule;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.lp.biz.coupon.mapper.BizCouponMemberRelMapper;
import com.lp.biz.coupon.model.entity.BizCouponMemberRel;
import com.lp.biz.member.mapper.MemberMapper;
import com.lp.biz.member.model.entity.Member;
import com.lp.biz.message.mapper.BizMessageIncomeMapper;
import com.lp.biz.message.model.entity.BizMessageIncome;
import com.lp.biz.order.mapper.BizOrderMapper;
import com.lp.biz.order.mapper.BizTradeIncomeLogMapper;
import com.lp.biz.order.model.dto.OrderInvitation;
import com.lp.biz.order.model.entity.BizOrder;
import com.lp.biz.order.model.entity.BizTradeIncomeLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

import static com.lp.common.constant.CommonConstant.NEGATE;
import static com.lp.common.constant.CommonConstant.SURE;
import static com.lp.common.constant.CouponConstant.STATUS_NOT_USED;
import static com.lp.common.constant.OrderConstant.STATUS_TIME_OUT_CANCELED;
import static com.lp.common.constant.OrderConstant.STATUS_UNPAID;

/**
 * @program: backend
 * @description: 订单定时任务
 * @author: Ke.Song
 * @since: 2024-06-20 22:46:11
 */
@Slf4j
@Component
public class OrderSchedule {

    @Value("${order.timeout}")
    private Integer timeOut;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private BizOrderMapper orderMapper;

    @Autowired
    private BizCouponMemberRelMapper relMapper;

    @Autowired
    private BizTradeIncomeLogMapper incomeLogMapper;

    @Autowired
    private BizMessageIncomeMapper messageIncomeMapper;

    @Scheduled(cron = "*/15 * * * * ?")
    @Transactional(rollbackFor = RuntimeException.class)
    public void checkTimeOut() {
        log.info("定时取消订单：开始");
        for (BizOrder bizOrder : orderMapper.selectList(new QueryWrapper<BizOrder>().lambda().eq(BizOrder::getStatus, STATUS_UNPAID)
                .le(BizOrder::getCreateAt, LocalDateTime.now().plusSeconds(7 - timeOut)))) {
            cancelOrder(bizOrder);
        }
        log.info("定时取消订单：结束");
    }

    @Scheduled(cron = "0 0 * * * ?")
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateBalance() {
        log.info("开始获取超过3天的订单");
        for (OrderInvitation temp : orderMapper.moreThan3Days()) {
            while (true) {
                log.info("开始处理。用户id：{}， 累计收益：{}，余额：{}，本地叠加：{}", temp.getMemberId(), temp.getIncome(),
                        temp.getBalance(), temp.getPrice());
                int update = memberMapper.update(null, new UpdateWrapper<Member>().lambda()
                        .eq(Member::getId, temp.getMemberId())
                        .eq(Member::getIncome, temp.getIncome())
                        .eq(Member::getBalance, temp.getBalance())
                        .set(Member::getIncome, temp.getIncome() == null ? temp.getPrice() : temp.getIncome().add(temp.getPrice()))
                        .set(Member::getBalance, temp.getBalance() == null ? temp.getPrice() : temp.getBalance().add(temp.getPrice())));
                if (update > 0) {
                    Set<Integer> collect = Arrays.stream(temp.getIds().split(",")).map(o -> Integer.valueOf(o.trim())).collect(Collectors.toSet());
                    if (!collect.isEmpty()) {
//                        for (Integer orderId : collect) {
//                            BizOrder order = orderMapper.selectById(orderId);
//                            // 插入消息收入记录
//                            BizMessageIncome bizMessageIncome = new BizMessageIncome();
//                            bizMessageIncome.setMemberId(temp.getMemberId());
//                            bizMessageIncome.setAmount(order.getKickbackCharge());
//                            bizMessageIncome.setSource(order.getOrderType());
//                            bizMessageIncome.setCreateAt(order.getPayAt());
//                            messageIncomeMapper.insert(bizMessageIncome);
//                            // 插入交易收入日志
//                            BizTradeIncomeLog bizTradeIncomeLog = new BizTradeIncomeLog();
//                            bizTradeIncomeLog.setMemberId(temp.getMemberId());
//                            bizTradeIncomeLog.setType(order.getOrderType());
//                            bizTradeIncomeLog.setBizOrderId(order.getId());
//                            bizTradeIncomeLog.setAmount(order.getKickbackCharge());
//                            bizTradeIncomeLog.setTradeAt(order.getPayAt());
//                            incomeLogMapper.insert(bizTradeIncomeLog);
//                        }
                        orderMapper.update(null, new UpdateWrapper<BizOrder>().lambda()
                                .in(BizOrder::getId, collect).set(BizOrder::getIsCalculated, SURE));
                    }
                    break;
                }
                Member member = memberMapper.selectById(temp.getMemberId());
                if (member == null) {
                    break;
                }
                temp.setBalance(member.getBalance());
                temp.setIncome(member.getIncome());
            }
        }
        log.info("超3天订单处理结束");
    }

    private void cancelOrder(BizOrder order) {
        log.info("定时取消订单：订单号 -> {}", order.getOrderNum());
        if (order.getStatus().equals(STATUS_UNPAID)) {
            int update = orderMapper.update(null, new UpdateWrapper<BizOrder>().lambda()
                    .eq(BizOrder::getId, order.getId())
                    .eq(BizOrder::getStatus, STATUS_UNPAID)
                    .set(BizOrder::getStatus, STATUS_TIME_OUT_CANCELED)
                    .set(BizOrder::getUpdateAt, LocalDateTime.now()));
            if (update != 1) {
                order = orderMapper.selectById(order.getId());
                cancelOrder(order);
            } else {
                if (order.getBizCouponId() != null) {
                    relMapper.update(null, new UpdateWrapper<BizCouponMemberRel>().lambda()
                            .eq(BizCouponMemberRel::getId, order.getBizCouponId())
                            .set(BizCouponMemberRel::getStatus, STATUS_NOT_USED)
                            .set(BizCouponMemberRel::getIsDeleted, NEGATE)
                            .set(BizCouponMemberRel::getUpdateAt, LocalDateTime.now()));
                }
                log.info("订单: {}超时被关闭, 关闭结果：{}", order.getOrderNum(), "成功");
            }
        } else {
            log.info("定时取消订单：订单号 -> {}，订单已经不是未支付，订单状态 -> {}", order.getOrderNum(), order.getStatus());
        }
    }
}
